home *** CD-ROM | disk | FTP | other *** search
- //=============================================================================
- //
- // Copyright (C) 1995,1996 by Paul S. McCarthy and Eric Sunshine.
- // Written by Paul S. McCarthy and Eric Sunshine.
- // All Rights Reserved.
- //
- // This notice may not be removed from this source code.
- //
- // This object is included in the MiscKit by permission from the authors
- // and its use is governed by the MiscKit license, found in the file
- // "License.rtf" in the MiscKit distribution. Please refer to that file
- // for a list of all applicable permissions and restrictions.
- //
- //=============================================================================
- //-----------------------------------------------------------------------------
- // DirArray.m
- //
- // An extensible array of directory entries.
- //
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- // $Id$
- // $Log$
- //-----------------------------------------------------------------------------
- #import "DirArray.h"
- #import <appkit/appkit.h>
- #import <assert.h>
-
-
- @implementation DirArray
-
- //-----------------------------------------------------------------------------
- // safeStrdup
- //-----------------------------------------------------------------------------
- - (char*) safeStrdup:(char const*)s
- {
- char* t = 0;
- if (s != 0)
- t = NXCopyStringBufferFromZone( s, [self zone] );
- return t;
- }
-
-
- //-----------------------------------------------------------------------------
- // safeFree
- //-----------------------------------------------------------------------------
- - (void) safeFree:(void*)p
- {
- if (p != 0)
- NXZoneFree( [self zone], p );
- }
-
-
- //-----------------------------------------------------------------------------
- // dirEntryCons
- //-----------------------------------------------------------------------------
- - (void) dirEntryCons: (DirEntry*) de
- name: (char const*) n
- path: (char const*) path
- {
- int rc;
- memset( de, 0, sizeof(*de) );
-
- de->dir = self;
- de->name = [self safeStrdup:n];
-
- if ((rc = lstat( path, &(de->st) )) == 0)
- {
- if ((de->st.st_mode & S_IFMT) == S_IFLNK) // soft-link?
- {
- char symbuf[ FILENAME_MAX + 1 ];
- int cc;
- cc = readlink( path, symbuf, FILENAME_MAX );
- if (cc >= 0)
- {
- symbuf[ cc ] = '\0';
- de->soft_link = [self safeStrdup:symbuf];
- rc = stat( path, &(de->st) );
- }
- else
- rc = -1;
- }
- }
-
- if (rc != 0)
- de->err = errno;
- }
-
-
- //-----------------------------------------------------------------------------
- // dirEntryDestroy:
- //-----------------------------------------------------------------------------
- - (void) dirEntryDestroy:(DirEntry*)de
- {
- if (de->image != 0)
- [de->image free];
- [self safeFree:de->name];
- [self safeFree:de->soft_link];
- }
-
-
- //-----------------------------------------------------------------------------
- // entryAt:
- //-----------------------------------------------------------------------------
- - (DirEntry const*)entryAt:(int)n
- {
- assert( 0 <=n && n < num_entries );
- return (entries + n);
- }
-
-
- //-----------------------------------------------------------------------------
- // isDir:
- //-----------------------------------------------------------------------------
- - (BOOL) isDir:(DirEntry const*)de
- {
- return ((de->st.st_mode & S_IFMT) == S_IFDIR);
- }
-
-
- //-----------------------------------------------------------------------------
- // isDirAt:
- //-----------------------------------------------------------------------------
- - (BOOL) isDirAt:(int)n
- {
- return [self isDir:[self entryAt:n]];
- }
-
-
- //-----------------------------------------------------------------------------
- // loadImage:
- //-----------------------------------------------------------------------------
- - (NXImage*) loadImage:(DirEntry*)de
- {
- char buff[ FILENAME_MAX + 1 ];
- char const* const dir_part = de->dir->name;
- int const dirlen = strlen( dir_part );
- memcpy( buff, dir_part, dirlen );
- strcpy( buff + dirlen, de->name );
- de->image = [[Application workspace] getIconForFile: buff];
- [de->image setScalable: YES];
- return de->image;
- }
-
-
- //-----------------------------------------------------------------------------
- // getImage:
- //-----------------------------------------------------------------------------
- - (NXImage*) getImage:(DirEntry const*)de
- {
- if (de->image == 0)
- [self loadImage:(DirEntry*)de];
- return de->image;
- }
-
-
- //-----------------------------------------------------------------------------
- // getImageAt:
- //-----------------------------------------------------------------------------
- - (NXImage*) getImageAt:(int)n
- {
- return [self getImage:[self entryAt:n]];
- }
-
-
- //-----------------------------------------------------------------------------
- // init
- //-----------------------------------------------------------------------------
- - init
- {
- [super init];
- total_bytes = 0;
- num_entries = 0;
- max_entries = 0;
- entries = 0;
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // empty
- //-----------------------------------------------------------------------------
- - (void) empty
- {
- DirEntry* p;
- for (p = entries + num_entries; p != entries; )
- [self dirEntryDestroy:--p];
- num_entries = 0;
- total_bytes = 0;
- }
-
-
- //-----------------------------------------------------------------------------
- // free
- //-----------------------------------------------------------------------------
- - free
- {
- [self empty];
- [self safeFree:name];
- [self safeFree:entries];
- return [super free];
- }
-
-
- //-----------------------------------------------------------------------------
- // count
- //-----------------------------------------------------------------------------
- - (int) count
- {
- return num_entries;
- }
-
-
- //-----------------------------------------------------------------------------
- // totalBytes
- //-----------------------------------------------------------------------------
- - (int) totalBytes
- {
- return total_bytes;
- }
-
-
- //-----------------------------------------------------------------------------
- // remove:
- //-----------------------------------------------------------------------------
- - (void) remove:(int)n
- {
- if (0 <= n && n < num_entries)
- {
- DirEntry* p = entries + n;
- total_bytes -= p->st.st_size;
- num_entries--;
- [self dirEntryDestroy:p];
- if (n < num_entries)
- memmove( p, p + 1, (num_entries - n) * sizeof(*p) );
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // expand
- //-----------------------------------------------------------------------------
- - (void) expand
- {
- DirEntry* p = entries;
- int N = max_entries;
- if (N == 0)
- {
- N = 16;
- p = (DirEntry*) NXZoneMalloc( [self zone], N * sizeof(*p) );
- }
- else
- {
- N += N;
- p = (DirEntry*) NXZoneRealloc( [self zone], p, N * sizeof(*p) );
- }
- max_entries = N;
- entries = p;
- }
-
-
- //-----------------------------------------------------------------------------
- // addName:path:
- //-----------------------------------------------------------------------------
- - (void) addName:(char const*)n path:(char const*)fullpath
- {
- DirEntry* p;
- if (num_entries >= max_entries)
- [self expand];
- p = entries + num_entries++;
- [self dirEntryCons:p name:n path:fullpath];
- total_bytes += p->st.st_size;
- }
-
-
- //-----------------------------------------------------------------------------
- // loadPath:showHidden:
- //-----------------------------------------------------------------------------
- - (int) loadPath:(char const*)path showHidden:(BOOL)showHidden
- {
- int rc = 0;
- int dirlen;
- DIR* dirp;
- char namebuff[ FILENAME_MAX + 1 ];
-
- dirlen = strlen( path );
- strcpy( namebuff, path );
- if (dirlen == 0 || namebuff[ dirlen - 1 ] != '/')
- {
- namebuff[ dirlen++ ] = '/';
- namebuff[ dirlen ] = '\0';
- }
-
- [self empty];
- [self safeFree:name];
- name = [self safeStrdup:namebuff];
-
- if ((dirp = opendir( path )) != 0)
- {
- struct direct const* dp;
-
- while ((dp = readdir(dirp)) != 0)
- { // Do not include the "." (self) entry.
- int const len = dp->d_namlen;
- char const* const nam = dp->d_name;
- BOOL const dot_name = (nam[0] == '.');
- if ((len > 1 || !dot_name) && // exclude "."
- (showHidden || !dot_name ||
- (len == 2 && nam[1] == '.'))) // include ".."
- {
- memcpy( namebuff + dirlen, nam, len + 1 );
- [self addName:nam path:namebuff];
- }
- }
-
- closedir( dirp );
- }
- else
- {
- rc = errno;
- }
-
- return rc;
- }
-
- @end
-